﻿using System;
using Internal.Runtime.Services.Battle.StateMachine;
using Runtime.Services.Battle;
using Runtime.Services.Battle.StateMachine;
using UnityEngine;

namespace Runtime.Services.Battle.StateMachine {

    /// <summary>
    /// 指定<see cref="UnityEngine.GameObject"/>进行显示的状态机
    /// </summary>
    public interface IDFR_BattleEntityStateMachine_SingleGameObject : IDFR_BattleEntityStateMachine {

        /// <summary>
        /// 显示状态提供者
        /// </summary>
        public interface IStateProvider {

            /// <summary>
            /// 要显示的对象
            /// </summary>
            GameObject GameObject { get; }
        }
    }

    [Implement(typeof(IDFR_BattleEntityStateMachine_SingleGameObject))]
    internal sealed class DFR_BattleEntityStateMachine_SingleGameObject : DFR_BattleEntityStateMachine, IDFR_BattleEntityStateMachine_SingleGameObject, IDFR_BattleEntityStateMachineInternal_SingleGameObject {

        private IDFR_BattleEntityAssetVehicle<IDFR_BattleEntityStateMachine_SingleGameObject.IStateProvider> m_StateVehicle;

        private GameObject m_IdleGameObject;

        private DFR_BattleEntityState m_LastState;

        private bool m_ForceRefreshState;
        public bool IsStateChanged => State != m_LastState;

        public override bool IsInitialized => m_IdleGameObject != null;

        private IParticleReferences m_IdleParticleReferences;

        private float m_PlaySpeed;

        void IDFR_BattleEntityStateMachineInternal_SingleGameObject.Initialize(IDFR_BattleEntityAssetVehicle<IDFR_BattleEntityStateMachine_SingleGameObject.IStateProvider> stateVehicle) {
            UnityEngine.Assertions.Assert.IsNotNull(stateVehicle);

            m_StateVehicle = stateVehicle;
            m_StateVehicle.Loaded += OnStateVehicleLoaded;
            OnStateVehicleLoaded();
        }

        protected override void Allocate() {
            base.Allocate();
            m_PlaySpeed = 0f;
            m_LastState = State = DFR_BattleEntityState.Unknown;
            m_ForceRefreshState = false;
        }

        protected override void Release() {
            if (ReleaseParticle(m_IdleParticleReferences)) {
                m_IdleParticleReferences = null;
            }

            m_IdleGameObject = null;

            m_StateVehicle = null;
        }

        private void OnStateVehicleLoaded() {
            if (m_StateVehicle.Content == null) {
                return;
            }

            m_IdleGameObject = m_StateVehicle.Content.GameObject;
            SetActive(m_LastState);

            m_ForceRefreshState = true;
            Play(m_PlaySpeed);
        }

        /// <summary>
        /// 等同于 m_IdleGameObject.SetActive(m_LastState == DFR_BattleEntityState.Idle);
        /// 展开判断主要是数量级调用时的CPU开销
        /// </summary>
        private void SetActive(DFR_BattleEntityState state) {
            if (state == DFR_BattleEntityState.Idle) {
                if (!m_IdleGameObject.activeSelf) {
                    m_IdleGameObject.SetActive(true);
                }
            } else {
                if (m_IdleGameObject.activeSelf) {
                    m_IdleGameObject.SetActive(false);
                }
            }
        }

        public override void Play(float speed) {
            if (IsDisposed) {
                return;
            }

            m_PlaySpeed = speed;

            if (!IsInitialized) {
                return;
            }
            if (State == DFR_BattleEntityState.Unknown) {
                return;
            }

            bool isStateChanged = IsStateChanged || m_ForceRefreshState;
            m_ForceRefreshState = false;
            if (isStateChanged) {
                SetActive(State);
                m_LastState = State;
            }

            ProcessParticle(isStateChanged, speed, m_IdleGameObject, ref m_IdleParticleReferences);
        }
    }
}

namespace Internal.Runtime.Services.Battle.StateMachine {

    public interface IDFR_BattleEntityStateMachineInternal_SingleGameObject : IDFR_BattleEntityStateMachine, IDisposable {

        void Initialize(IDFR_BattleEntityAssetVehicle<IDFR_BattleEntityStateMachine_SingleGameObject.IStateProvider> stateVehicle);
    }
}